using System.Collections.Generic;
using System.Linq;
using System;
using System.Xml;

namespace SolutionOrchestrator.Validators
{
	public class AllwaysCopyValidator : XmlFileValidator
	{
		public AllwaysCopyValidator()
		{
			IsEnabled = true;
		}

		class AllwaysCopyViolation : FixableViolation
		{
			class AllwaysCopyFix : Fix
			{
				readonly string _id;

				public AllwaysCopyFix(string id) : base(true)
				{
					_id = id;
				}

				#region Overrides of Fix

				public override string ToString()
				{
					return "Copy if newer";
				}

				public override bool Equals(object other)
				{
					return Equals(other as AllwaysCopyFix);
				}

				public bool Equals(AllwaysCopyFix fix)
				{
					if (fix == null)
					{
						return false;
					}
					return fix._id == _id;
				}

				public override int GetHashCode()
				{
					return _id.GetHashCode();
				}

				#endregion
			}


			XmlNode _node;
			readonly string _fileName;
			XmlDoc _doc;

			public AllwaysCopyViolation(XmlDoc doc, XmlNode node, string fileName)
			{
				_node = node;
				_fileName = fileName;
				_doc = doc;
			}

			#region Overrides of FixableViolation

			protected override IEnumerable<Fix> FixesAvailableCore
			{
				get { yield return new AllwaysCopyFix(_doc.FileName+"#"+_fileName); }
			}

			protected override void ApplyFixCore(Fix fix)
			{
				_node.SelectSingleNode("x:CopyToOutputDirectory", _doc.Nm).InnerText = "PreserveNewest";
				_doc.Save();
			}

			#endregion
		}

		#region Overrides of XmlFileValidator

		protected override IEnumerable<Violation> Validate(XmlDoc doc, ValidationContext ctx)
		{
			foreach (var node in doc.Select("x:Project/x:ItemGroup/*[x:CopyToOutputDirectory='Always' and @Include]"))//
			{
				var file = node.Attributes["Include"].Value;
				yield return new AllwaysCopyViolation(doc, node, file) {FullPath = doc.FileName, Description = "Copy Allways: " + file};
			}
		}

		#endregion
	}
}